Don't lose error traces in manifest parse errors
authorAlex Crichton <alex@alexcrichton.com>
Thu, 15 Jan 2015 19:12:13 +0000 (11:12 -0800)
committerAlex Crichton <alex@alexcrichton.com>
Fri, 16 Jan 2015 16:45:08 +0000 (08:45 -0800)
Closes #1174

src/cargo/ops/cargo_read_manifest.rs
src/cargo/util/errors.rs
src/cargo/util/toml.rs
tests/test_bad_config.rs

index 9314736d936bb8d235c514395c87f81b80f1ccfc..3dc1aba68968beb32ab049719278a6132d5668a3 100644 (file)
@@ -4,7 +4,7 @@ use std::io::fs::PathExtensions;
 use std::io::{self, File, fs};
 
 use core::{Package,Manifest,SourceId};
-use util::{self, CargoResult, human, Config};
+use util::{self, CargoResult, human, Config, ChainError};
 use util::important_paths::find_project_manifest_exact;
 use util::toml::{Layout, project_layout};
 
@@ -12,9 +12,9 @@ pub fn read_manifest(contents: &[u8], layout: Layout, source_id: &SourceId,
                      config: &Config)
                      -> CargoResult<(Manifest, Vec<Path>)> {
     let root = layout.root.clone();
-    util::toml::to_manifest(contents, source_id, layout, config).map_err(|e| {
-        human(format!("failed to parse manifest at `{:?}`\n{}",
-                      root.join("Cargo.toml"), e))
+    util::toml::to_manifest(contents, source_id, layout, config).chain_error(|| {
+        human(format!("failed to parse manifest at `{:?}`",
+                      root.join("Cargo.toml")))
     })
 }
 
index 688b30b1f66dc6d0fed5413cf8c05234a25cf944..6a906aab27c465b63bf5ab7f67bca762116dea4c 100644 (file)
@@ -8,9 +8,9 @@ use semver;
 use rustc_serialize::json;
 
 use curl;
-use toml::Error as TomlError;
-use url;
 use git2;
+use toml;
+use url;
 
 pub type CargoResult<T> = Result<T, Box<CargoError>>;
 
@@ -228,8 +228,9 @@ from_error! {
     json::DecoderError,
     curl::ErrCode,
     CliError,
-    TomlError,
+    toml::Error,
     url::ParseError,
+    toml::DecodeError,
 }
 
 impl<E: Error> FromError<Human<E>> for Box<CargoError> {
@@ -243,7 +244,8 @@ impl CargoError for json::DecoderError {}
 impl CargoError for curl::ErrCode {}
 impl CargoError for ProcessError {}
 impl CargoError for CliError {}
-impl CargoError for TomlError {}
+impl CargoError for toml::Error {}
+impl CargoError for toml::DecodeError {}
 impl CargoError for url::ParseError {}
 
 // =============================================================================
index b7321d46e4bd6e054a4db2ba8a274f6f42b15785..7addd794c776d947ce34fd1cbc8b6ab314c8aedc 100644 (file)
@@ -104,17 +104,9 @@ pub fn to_manifest(contents: &[u8],
     }));
     let root = try!(parse(contents, &manifest));
     let mut d = toml::Decoder::new(toml::Value::Table(root));
-    let toml_manifest: TomlManifest = match Decodable::decode(&mut d) {
-        Ok(t) => t,
-        Err(e) => return Err(human(format!("{} is not a valid \
-                                            manifest\n\n{}",
-                                           manifest.display(), e)))
-    };
+    let toml_manifest: TomlManifest = try!(Decodable::decode(&mut d));
 
-    let pair = try!(toml_manifest.to_manifest(source_id, &layout, config).map_err(|err| {
-        human(format!("{} is not a valid manifest\n\n{}",
-                      manifest.display(), err))
-    }));
+    let pair = try!(toml_manifest.to_manifest(source_id, &layout, config));
     let (mut manifest, paths) = pair;
     match d.toml {
         Some(ref toml) => add_unused_keys(&mut manifest, toml, "".to_string()),
index ad179ecd5f28a7bc3421b3c32e90349555be60d1..3b23fd3fff4c3945c53b51d78ea9d75ea285d7de 100644 (file)
@@ -141,3 +141,34 @@ test!(good_cargo_config_jobs {
     assert_that(foo.cargo_process("build").arg("-v"),
                 execs().with_status(0));
 });
+
+test!(invalid_global_config {
+    let foo = project("foo")
+    .file("Cargo.toml", r#"
+        [package]
+        name = "foo"
+        version = "0.0.0"
+        authors = []
+
+        [dependencies]
+        foo = "0.1.0"
+    "#)
+    .file(".cargo/config", "4")
+    .file("src/lib.rs", "");
+
+    assert_that(foo.cargo_process("build").arg("-v"),
+                execs().with_status(101).with_stderr("\
+failed to parse manifest at `[..]Cargo.toml`
+
+Caused by:
+  Couldn't load Cargo configuration
+
+Caused by:
+  could not parse TOML configuration in `[..]config`
+
+Caused by:
+  could not parse input as TOML
+[..]config:2:1 expected `=`, but found eof
+
+"));
+});